package com.hongkzh.www.adv.service;

import com.google.common.collect.Lists;
import com.hongkzh.www.conmon.*;
import com.hongkzh.www.user.service.UserService;
import com.jfinal.aop.Before;
import com.jfinal.aop.Enhancer;
import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.SqlPara;
import com.jfinal.plugin.activerecord.tx.Tx;
import redis.clients.jedis.GeoRadiusResponse;
import redis.clients.jedis.GeoUnit;
import redis.clients.jedis.params.geo.GeoRadiusParam;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class CityService extends BaseService {
    static AdvService advService = new AdvService();

    public List<Record> getHots() {
        SqlPara sqlPara = Db.getSqlPara("city.getHots");
        List<Record> hots = Db.find(sqlPara);
        for (Record r : hots
        ) {
            doFilePath(r);
        }
        return hots;
    }

    public Page<Record> getCityAdvList(int pageNumber) {
        SqlPara sqlPara = Db.getSqlPara("city.getCityAdvList");
        Page<Record> records = Db.paginate(pageNumber, StaticPublic.PAGESIZE, sqlPara);

        SqlPara sqlPara1 = Db.getSqlPara("city.getCityAdvRedPackets");
        Page<Record> recordPage = Db.paginate(pageNumber ,3 , sqlPara1);

//        List<Record> statics = advService.getStaticListByType("3");
        LinkedList<Record> llist = new LinkedList<>();
        for (Record r : records.getList()) {
            r.set("advType", 1);
            doFilePath(r);
            llist.add(r);
//            for (Record static1 : statics
//            ) {
//                if (0 == MathRandom.PercentageRandom()) {
//                    static1.set("advType", 2);
//                    llist.add(static1);
//                    break;
//                }
//            }
        }
        for (Record r : recordPage.getList()) {
            r.set("advType", 1);
            doFilePath(r);
            llist.add(r);
        }
        Collections.shuffle(llist);
        Page<Record> records2 = new Page<Record>(llist, records.getPageNumber(), records.getPageSize(), records.getTotalPage(), records.getTotalRow());


        return records2;
    }

    private void initMediaDataByCategory() {
        String key = String.format(StaticPublic.GEOCITYEXITSKEY);
        String categoryKey = String.format(StaticPublic.GEOCITYKEY);
        if (!RedisTool.exists(key)) {
            RedisTool.del(categoryKey);
            SqlPara sqlPara = Db.getSqlPara("city.getALLCityList");
            List<Record> records = Db.find(sqlPara);
            if (null != records && records.size() > 0) {
                RedisTool.setex(key, StaticPublic.GEOCITYEXITSKEYTIME, "1");
                for (Record r : records) {
                    RedisTool.geoadd(categoryKey, r.getDouble("longitude"), r.getDouble("latitude"), r.getStr("id"));
                }
            }

        }
    }

    public Page<Record> getCityNearbyAdvList(double latitude, double longitude, int pageNumber) {
        {
            SqlPara sqlPara;
            String categoryKey = String.format(StaticPublic.GEOCITYKEY);
            initMediaDataByCategory();
            List<Record> records = Lists.newArrayList();
            Page<Record> p = new Page<Record>(records, pageNumber, StaticPublic.PAGESIZE, 0, 0);
            List<GeoRadiusResponse> list = RedisTool.georadius(categoryKey, longitude, latitude, StaticPublic.BAI, GeoUnit.KM, GeoRadiusParam.geoRadiusParam().withDist().sortAscending().count(100));

           /* sqlPara = Db.getSqlPara("city.getCount");
            Record count= Db.findFirst(sqlPara);*/
            int totalRow = list.size();// count.getLong("count").intValue();
            //totalRow=totalRow>list.size()?list.size():totalRow;
            int totalPage = (int) (totalRow / StaticPublic.PAGESIZE);
            if (totalRow % (long) StaticPublic.PAGESIZE != 0L) {
                ++totalPage;
            }

            if (null != list && list.size() > 0 && list.size() >= StaticPublic.PAGESIZE * (pageNumber - 1)) {
                list.subList(0, StaticPublic.PAGESIZE * (pageNumber - 1)).clear();
            } else {
                list = Collections.emptyList();
            }

//            List<Record> statics = advService.getStaticListByType("3");
            for (GeoRadiusResponse g : list) {
                String id = new String(g.getMember());
                sqlPara = Db.getSqlPara("city.getCityAdvById", id);
                Record r = Db.findFirst(sqlPara);
                if (null != r) {
                    r.set("advType", 1);
                    r.set("distance", g.getDistance());
                    doFilePath(r);

                    records.add(r);
//                    for (Record static1 : statics
//                    ) {
//                        if (0 == MathRandom.PercentageRandom()) {
//                            static1.set("advType", 2);
//                            records.add(static1);
//                            break;
//                        }
//                    }
                }
            }
            if (null != records && records.size() > 0) {
                p = new Page<Record>(records, pageNumber, StaticPublic.PAGESIZE, totalPage, totalRow);
            }
            return p;

        }
    }

    public Page<Record> getAllHots(int pageNumber) {
        SqlPara sqlPara = Db.getSqlPara("city.getAllHots");
        Page<Record> records = Db.paginate(pageNumber, StaticPublic.PAGESIZE, sqlPara);
        for (Record r : records.getList()
        ) {
            doFilePath(r);
        }
        return records;
    }

    public Record getCityInfoById(String cityId, String freginCity) throws Exception {
        Kv cond = Kv.by("cityId", cityId).set("freginCity", freginCity);
        SqlPara sqlPara = Db.getSqlPara("city.getCityInfoById", cond);
        Record r = Db.findFirst(sqlPara);
        if (null == r) {
            return null;
        }

        sqlPara = Db.getSqlPara("city.getCityCategoryListById", cond);
        List<Record> categorys = Db.find(sqlPara);
        r.set("categorys", null);
        if (null != categorys && categorys.size() > 0) {
            r.set("categorys", categorys);
        }
        doImgPath(r);
        return r;
    }


    public Page<Record> getCategoryCityAdvList(int pageNumber, String cityId, String categoryId,String freginCity) {

        SqlPara sqlPara;
        Kv cond;

       /* LinkedList<Record> llist = new LinkedList<>();
        cond = Kv.by("cityId", cityId);
        sqlPara = Db.getSqlPara("city.getMediaAdvRedPackets", cond);
        Page<Record> recordPage = Db.paginate(pageNumber , StaticPublic.PAGESIZE ,sqlPara);

        for (Record r : recordPage.getList()) {
            r.set("advType" , 1);
            doImgPath(r);
            doNumberPath(r);
            llist.add(r);
        }*/


        if ("-999".equals(cityId)){
            cond = Kv.by("freginCity", freginCity).set("categoryId", categoryId).set("freginCity",freginCity);
            sqlPara = Db.getSqlPara("city.getCategoryCityAdvListByCityName", cond);
        }else{
            cond = Kv.by("cityId", cityId).set("categoryId", categoryId).set("cityId",cityId);
            sqlPara = Db.getSqlPara("city.getCategoryCityAdvListByCityId", cond);
        }

        Page<Record> records = Db.paginate(pageNumber, StaticPublic.PAGESIZE, sqlPara);

      /*  for (Record r : records.getList()) {
            r.set("advType", 1);
            doImgPath(r);
            doNumberPath(r);
            llist.add(r);
*/
     List<Record> res = new ArrayList<>();
         for (Record r : records.getList()
         ) {
            r.set("advType", 1);
            doImgPath(r);
            doNumberPath(r);
            res.add(r);

//            for (Record static1 : statics
//            ) {
//                if (0 == MathRandom.PercentageRandom()) {
//                    static1.set("advType", 2);
//                    res.add(static1);
//                    break;
//                }
//            }
        }
//        Collections.shuffle(llist);
        return new Page<Record>(res, records.getPageNumber(), records.getPageNumber(), records.getTotalPage(), records.getTotalRow());
    }

    public Record getCityAdvInfo(String cityAdvId, String uid) {
        SqlPara sqlPara = Db.getSqlPara("city.getCityAdvInfo", cityAdvId, uid);
        Record record = Db.findFirst(sqlPara);
        if (null != record) {
            doImgPath(record);
            doNumberPath(record);
            record.set("createDate", DateUtil.FormatDate2(record.get("createDate")));
            record.set("collectionState", "0");
            if (StrKit.notBlank(record.getStr("collectionId"))) {
                record.set("collectionState", "1");
            }
            record.set("praiseState", "0");
            if (StrKit.notBlank(record.getStr("praiseId"))) {
                record.set("praiseState", "1");
            }


            sqlPara = Db.getSqlPara("city.getCityImgsList", cityAdvId);
            List<Record> list = Db.find(sqlPara);
            if (null != list) {
                for (Record r : list
                ) {
                    doFilePath(r);
                }
                record.set("imgs", list);
            }
            sqlPara = Db.getSqlPara("city.getCityUserProductList", cityAdvId);
            List<Record> products = Db.find(sqlPara);
            record.set("products", null);
            if (null != products && products.size() > 0) {
                record.set("products", products);
            }

        }

        return record;
    }

    public Record getCityAdvMediaInfo(String cityAdvId, String uid) {

        {
            SqlPara sqlPara = Db.getSqlPara("city.getCityAdvInfo", cityAdvId, uid);
            Record record = Db.findFirst(sqlPara);
            if (record == null) {
                throw new BusinessException("网络异常！");
            }
            if (null != record) {
                record.set("isRed", 0);
                if (record.getInt("totalMoney") > 0) {
                    record.set("isRed", 1);
                }
                record.set("imgSrc1", record.getStr("imgSrc"));
                doImgPath(record);
                doNumberPath(record);
                record.set("imgSrc", record.getStr("imgSrc1"));
                record.set("createDate", DateUtil.FormatDate2(record.get("createDate")));
                record.set("collectionState", "0");
                if (StrKit.notBlank(record.getStr("collectionId"))) {
                    record.set("collectionState", "1");
                }
                record.set("praiseState", "0");
                if (StrKit.notBlank(record.getStr("praiseId"))) {
                    record.set("praiseState", "1");
                }
                sqlPara = Db.getSqlPara("city.getCityUserProductList", cityAdvId);
                List<Record> products = Db.find(sqlPara);
                record.set("products", null);
                if (null != products && products.size() > 0) {
                    record.set("products", products);
                }
                sqlPara = Db.getSqlPara("city.getCityTagList", cityAdvId);
                List<Record> tags = Db.find(sqlPara);
                record.set("tags", null);
                if (null != tags && tags.size() > 0) {
                    record.set("tags", tags);
                }
                record.set("nextMediaAdvId", "");
                sqlPara = Db.getSqlPara("city.nextCityAdvId", cityAdvId);
                Record r2 = Db.findFirst(sqlPara);
                if (null != r2) {
                    record.set("nextMediaAdvId", r2.get("id"));
                }
            }

            return record;
        }
    }

    @Before(Tx.class)
    public void saveCityAdv(String title, String content, String coverImgSrcImg, String[] products, String isShowArea,
                            String loginUid, String categoryId, String cityId, String cityAdvId,
                            String coverImgWidth, String coverImgHeight) {
        String provinceId = RedisTool.hget("area:" + cityId, "parentId");
        Kv cond = Kv.by("title", title).set("coverImgSrc", coverImgSrcImg).set("coverImgWidth", coverImgWidth)
                .set("coverImgHeight", coverImgHeight).set("category", categoryId).set("cityId", cityId)
                .set("uid", loginUid).set("note", content).set("provinceId", provinceId);
        if (StrKit.notBlank(cityAdvId)) {
            cond.set("cityAdvId", cityAdvId);
            Db.update(Db.getSqlPara("city.updateCityAdv", cond));
            Db.update(Db.getSqlPara("adv.updateCityAdv", cond));
            //先删除分类在增加分类
            Db.update(Db.getSqlPara("city.deleteAdvCategory", cityAdvId));
            Db.update(Db.getSqlPara("adv.deleteAlladvCategory", cityAdvId));
            Db.update(Db.getSqlPara("adv.saveAlladvCategory", categoryId, cityAdvId));
            Db.update(Db.getSqlPara("city.saveAdvCategory", categoryId, cityAdvId));

        } else {
            cityAdvId = IdGen.uuid();
            cond.set("cityAdvId", cityAdvId);
            cond.set("id", IdGen.uuid());
            Db.update(Db.getSqlPara("city.saveCityAdv", cond));
            Db.update(Db.getSqlPara("adv.saveCityAdv", cond));
            Db.update(Db.getSqlPara("adv.saveAlladvCategory", categoryId, cityAdvId));
            Db.update(Db.getSqlPara("city.saveAdvCategory", categoryId, cityAdvId));

        }
        if (null != products && products.length > 0) {
            Db.update(Db.getSqlPara("city.deleteAdvProduct", cityAdvId));
            for (String p : products
            ) {
                Db.update(Db.getSqlPara("city.saveAdvProduct", cityAdvId, p, IdGen.uuid()));
            }

        }


    }

    @Before(Tx.class)
    public String reward(String uid, String id, Integer money) throws Exception {
        Record r = Db.findFirst(Db.getSqlPara("media.getAdvById", id, uid));
        if (r == null) {
            throw new BusinessException("网络异常！");
        }
        UserService us = Enhancer.enhance(UserService.class);
        us.reduceIntegral(uid, money, "打赏消费");
        us.addIntegral(r.getStr("uid"), money, "收入");
        int i = Db.update(Db.getSqlPara("adv.updateDataReward", id, money));
        if (i == 0) {
            Db.update(Db.getSqlPara("adv.insertDataReward", IdGen.uuid(), id, money));
        }
        return Db.findFirst(Db.getSqlPara("adv.getDataReward", id)).getStr("rewardCount");
    }
}
